from odoo import models, fields, api, _
from odoo.exceptions import ValidationError

STATE = [
    ('draft', 'Draft'),
    ('wait_approval', 'Waiting for Approval'),
    ('approved', 'Approved'),
    ('rejected', 'Rejected'),
    ('done', 'Done')]


class ProductCodingTemplate(models.Model):
    _inherit = 'product.coding.template'

    def get_default_workflow_template(self):
        wt = self.env['sb.workflow.template'].sudo().search([('workflow_type', 'in', ['coding_template'])],
                                                            limit=1)
        return wt.id

    # 审批流字段  start
    sb_workflow_template_id = fields.Many2one('sb.workflow.template', string="Approval Workflow Template",
                                              domain="[('sb_workflow_template_item_ids', '!=', False),"
                                                     "('workflow_type', 'in', ['other', 'coding_template'])]",
                                              default=get_default_workflow_template)
    sb_workflow_id = fields.Many2one('sb.workflow', string="Current Approval Workflow", copy=False)
    sb_workflow_state = fields.Selection(related="sb_workflow_id.state", readonly=True, store=True,
                                         string="Approval Status", tracking=True)
    user_group_ids = fields.Many2many('res.users', 'product_coding_template_workflow_rel',
                                      'template_id', 'workflow_id',
                                      compute='compute_b_workflow_user_group', store=True)
    sb_workflow_item_ids = fields.One2many(related="sb_workflow_id.sb_workflow_item_ids", string="Approval Items")
    sb_workflow_attachments_ids = fields.One2many(related="sb_workflow_id.sb_workflow_attachments_ids",
                                                  string="Approval Attachments")
    sb_workflow_ids = fields.One2many('sb.workflow', 'product_coding_id', string="Approval Workflows")
    state = fields.Selection(STATE, string='state', default='draft', compute='_compute_state', store=True,
                             tracking=True, readonly=False)
    # 审批发起人
    approval_id = fields.Many2one('res.users', string='Approval Initiator', copy=False)
    approval_button = fields.Boolean(string='Approval Button', compute='compute_approval_button')
    approval_user_ids = fields.Many2many('res.users', compute='compute_sb_workflow_item_ids_state',
                                         string='Approval Users', store=True)

    # 审批流字段  end

    def compute_approval_button(self):
        for rec in self:
            ap = rec.sb_workflow_item_ids.filtered(lambda x: x.state == 'approval' and x.is_approval is True)
            if ap:
                rec.approval_button = True
            else:
                rec.approval_button = False

    def approval_order(self):
        """
        批量审批通过, 设为弹窗后只能执行一条审批
        """
        self.ensure_one()
        ap = self.sb_workflow_item_ids.filtered(lambda x: x.state == 'approval' and x.is_approval)
        if not ap:
            return
        rec = ap[0].review()
        rec['context'].update({
            'un_active': True
        })
        return rec

    def pass_approve(self):
        for rec in self:
            if rec.sb_workflow_state != 'approval':
                continue
            rr = rec.sb_workflow_id.sb_workflow_item_ids.filtered(lambda x: x.state == 'approval')
            user_approval = rr.filtered(lambda x: self.env.user.id in x.user_group_ids.ids)
            for item in user_approval:
                self.env['workflow.check.wizard'].create([{'sb_workflow_item_id': item.id,
                                                           'planned_receiving_date': False,
                                                           'approval_instructions': '审批通过'}]).approval_pass()
            if rec.sb_workflow_state=='approve' and not rec.sb_workflow_template_id:
                rec.button_done()  # 审批通过完成订单


    def reject_approve(self):
        for rec in self:
            if rec.sb_workflow_state != 'approval':
                continue
            rr = rec.sb_workflow_id.sb_workflow_item_ids.filtered(lambda x: x.state == 'approval')
            user_approval = rr.filtered(lambda x: self.env.user.id in x.user_group_ids.ids)
            for item in user_approval:
                self.env['workflow.check.wizard'].create([{'sb_workflow_item_id': item.id,
                                                           'planned_receiving_date': False,
                                                           'approval_instructions': '审批驳回'}]).approval_no_pass()

    @api.onchange('sb_workflow_state')
    @api.depends('sb_workflow_state')
    def _compute_state(self):
        for item in self:
            if item.sb_workflow_state == 'approve':
                item.state = 'approved'
                if not item.product_tmpl_id:
                    item.button_done()  # 审批通过完成订单
            elif item.sb_workflow_state == 'approval':
                item.state = 'wait_approval'
            elif item.sb_workflow_state == 'fail_to_approve':
                item.state = 'rejected'
            else:
                item.state = 'draft'

    def create_workflow(self):
        self.ensure_one()

        if self.name:
            tml_name = self.env['product.template'].search([('name', '=', self.name)])
            if tml_name:
                raise ValidationError('Duplicate material description!')
        # 只要存在false就不允许通过
        # if not all(self.product_coding_attribute_ids.filtered(lambda x: x.coding_attribute_type != 'desc_input').mapped(
        #         'material_coding_attribute_value_code')):
        #     raise ValidationError('Please select at least one material coding attribute.')
        # 验证明细, 供应商选择是需要明细为供应商必填, 部门如此
        # supplier = []
        # department = []
        # for rec in self.product_coding_attribute_ids:
        #     if self.department_choice == 'single' and rec.coding_attribute_type == 'department':
        #         if not rec.department_id:
        #             department.append(1)
        #     if self.supplier_choice == 'yes' and rec.coding_attribute_type == 'partner':
        #         if not rec.coding_provider_id:
        #             supplier.append(1)
        # if supplier and department:
        #     return {
        #         'type': 'ir.actions.client',
        #         'tag': 'display_notification',
        #         'params': {
        #             'title': _('Operation failure'),
        #             'message': _('Please select a supplier and department'),
        #             'sticky': False,  # 设置为 False，表示通知不会一直显示
        #             'timeout': 5000,  # 设置通知显示的时间（单位：毫秒），此处为 5 秒
        #         },
        #     }
        # if supplier:
        #     return {
        #         'type': 'ir.actions.client',
        #         'tag': 'display_notification',
        #         'params': {
        #             'title': _('Operation failure'),
        #             'message': _('Please select a supplier'),
        #             'sticky': False,  # 设置为 False，表示通知不会一直显示
        #             'timeout': 5000,  # 设置通知显示的时间（单位：毫秒），此处为 5 秒
        #         },
        #     }
        # if department:
        #     return {
        #         'type': 'ir.actions.client',
        #         'tag': 'display_notification',
        #         'params': {
        #             'title': _('Operation failure'),
        #             'message': _('Please select a department'),
        #             'sticky': False,  # 设置为 False，表示通知不会一直显示
        #             'timeout': 5000,  # 设置通知显示的时间（单位：毫秒），此处为 5 秒
        #         },
        #     }
        self.search_arg = ''
        self.template_ids = None
        if self.sb_workflow_template_id:
            if len(self.sb_workflow_ids) > 0:
                workflow_sum = len(self.sb_workflow_ids) + 1
            else:
                workflow_sum = 1
            self.state = 'wait_approval'
            if self.name == 'Draft' or not self.name:
                self.name = self.env['ir.sequence'].next_by_code('product.apply.serial')
            # 创建审批流
            new_wf_id = self.env['sb.workflow'].sudo().create({
                'name': self.name + '- Approval Flow' + '-' + str(workflow_sum),
                'approval_time': fields.Datetime.now(),
                'workflow_type': 'coding_template',
                'product_coding_id': self.id,
            })
            self.sb_workflow_id = new_wf_id.id
            # self.approval_id = self.env.uid
            # 根据模板生成审批项
            item_audit_levels = []
            for item in self.sb_workflow_template_id.sb_workflow_template_item_ids:
                new_item = self.env['sb.workflow.item'].sudo().create({
                    'name': item.name,
                    'user_group_ids': item.user_group_ids.ids,
                    'audit_level': item.audit_level,
                    'sb_workflow_id': new_wf_id.id,
                    'state': 'wait_forward'
                })
                # 收集生成的审核项的所有层级
                item_audit_levels.append(new_item.audit_level)
            # 去重排序
            item_audit_levels = list(set(item_audit_levels))
            item_audit_levels.sort()
            # 开放最低层级的神匹配
            for n_item in new_wf_id.sb_workflow_item_ids:
                if n_item.audit_level == item_audit_levels[0]:
                    n_item.state = 'approval'
            self.approval_id = self.env.uid
        else:
            raise ValidationError('Please select an approval template.')

    @api.depends('sb_workflow_ids')
    def _compute_sb_workflow_ids_sum(self):
        for item in self:
            if item.sb_workflow_ids:
                item.sb_workflow_ids_sum = len(item.sb_workflow_ids)
            else:
                item.sb_workflow_ids_sum = 0

    @api.depends('sb_workflow_item_ids', 'sb_workflow_item_ids.state')
    def compute_sb_workflow_item_ids_state(self):
        for item in self:
            ap = item.sb_workflow_item_ids.filtered(lambda x: x.state == 'approval')
            if ap.mapped('user_group_ids').ids:
                item.approval_user_ids = [(6, 0, ap.mapped('user_group_ids').ids)]
            else:
                item.approval_user_ids = [(5,)]

    @api.depends('sb_workflow_item_ids', 'sb_workflow_item_ids.state')
    def compute_b_workflow_user_group(self):
        for item in self:
            ap = item.sb_workflow_item_ids.filtered(lambda x: x.state == 'pass')
            if ap.mapped('user_group_ids').ids:
                item.user_group_ids = [(6, 0, ap.mapped('user_group_ids').ids)]
            else:
                item.user_group_ids = [(5,)]

    def action_view_workflow(self):
        return {
            'name': 'Approval Flow',
            'type': 'ir.actions.act_window',
            'res_model': 'sb.workflow',
            'view_mode': 'tree',
            'target': 'current',
            'domain': [('product_coding_id', '=', self.id)],
        }

    def action_workflow(self):
        return {
            'name': 'Approval Flow',
            'type': 'ir.actions.act_window',
            'res_model': 'sb.workflow',
            'view_mode': 'form',
            'res_id': self.sb_workflow_id.id,
            'target': 'current',
        }

    def button_withdraw(self):
        """
        撤回审批申请
        1. 撤回审批中, 审批通过订单
        2. 条件: 如关联产品, 需产品删除或归档才可撤回
        3. 删除审批流程
        4. 按钮需要权限, 仅限管理员撤回
        """
        for record in self:
            if record.sb_workflow_state not in ['approval', 'approve']:  # 其他审批状态不做处理
                continue
            # 检查当前订单是否支持撤回
            if record.check_withdraw_product():
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': _('Failure to withdraw'),
                        'message': _(
                            'The product associated with the approval process exists. Please delete or archive the product before withdrawing it.'),
                        'sticky': False,  # 设置为 False，表示通知不会一直显示
                        'timeout': 5000,  # 设置通知显示的时间（单位：毫秒），此处为 5 秒
                    },
                }
            update_dict = {'state': 'draft', 'approval_id': False}
            # 先判断是否存在产品
            if record.product_tmpl_id:
                # 绑定上历史审批生成的产品
                update_dict.update({
                    'product_tmpl_ids': [(4, record.product_tmpl_id.id)],
                    'product_tmpl_id': False,
                })
            # 归档审批流程
            record.sb_workflow_ids.write({'active': False})
            record.write({'sb_workflow_ids': [(3, record.sb_workflow_id.id)]})
            record.write(update_dict)

    def check_withdraw_product(self):
        """
        存在商品
        """
        if not self.product_tmpl_id:
            return
        # 条件: 如关联产品, 需产品删除或归档才可撤回
        if self.product_tmpl_id.product_variant_ids:
            return True
        return
